home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * xanim_fli.c
- *
- * Copyright (C) 1990,1991,1992 by Mark Podlipec.
- * All rights reserved.
- *
- * This software may be freely copied, modified and redistributed
- * without fee provided that this copyright notice is preserved
- * intact on all copies and modified copies.
- *
- * There is no warranty or other guarantee of fitness of this software.
- * It is provided solely "as is". The author(s) disclaim(s) all
- * responsibility and liability with respect to this software's usage
- * or its effect upon hardware or computer systems.
- *
- */
- #include <stdio.h>
- #include "mytypes.h"
- #include "xanim.h"
- #include "xanim_fli.h"
-
- void Read_Fli_Header();
- void Read_Fli_Frame_Header();
- void Read_Fli_File();
- void Decode_Fli_BRUN();
- void Decode_Fli_LC();
- void Read_Fli_COLOR();
- void Fli_Buffer_Action();
-
- ULONG Fli_Get_Word();
- ULONG Fli_Get_HalfWord();
-
- static Fli_Header fli_hdr;
- static Fli_Frame_Header frame_hdr;
-
- void Read_Fli_Header(fp,fli_hdr)
- FILE *fp;
- Fli_Header *fli_hdr;
- {
- int i;
-
- fli_hdr->size = Fli_Get_Word(fp);
- fli_hdr->magic = Fli_Get_HalfWord(fp);
- fli_hdr->frames = Fli_Get_HalfWord(fp);
- fli_hdr->width = Fli_Get_HalfWord(fp);
- fli_hdr->height = Fli_Get_HalfWord(fp);
- fli_hdr->res1 = Fli_Get_HalfWord(fp);
- fli_hdr->flags = Fli_Get_HalfWord(fp);
- fli_hdr->speed = Fli_Get_HalfWord(fp);
- fli_hdr->next = Fli_Get_Word(fp);
- fli_hdr->frit = Fli_Get_Word(fp);
- for(i=0;i<102;i++) fgetc(fp); /* ignore unused part of Fli_Header */
-
- imagex=fli_hdr->width;
- imagey=fli_hdr->height;
- if ( (fli_hdr->magic != 0xaf11) && (fli_hdr->magic != 0xaf12) )
- {
- fprintf(stderr,"imagex=%lx imagey=%lx\n",imagex,imagey);
- fprintf(stderr,"Fli Header Error magic %lx not = 0xaf11\n",fli_hdr->magic);
- TheEnd();
- }
- }
-
- void Read_Fli_Frame_Header(fp,frame_hdr)
- FILE *fp;
- Fli_Frame_Header *frame_hdr;
- {
- int i;
-
- frame_hdr->size = Fli_Get_Word(fp);
- frame_hdr->magic = Fli_Get_HalfWord(fp);
- frame_hdr->chunks = Fli_Get_HalfWord(fp);
- for(i=0;i<8;i++) fgetc(fp); /* ignore unused part of Fli_Frame_Header */
-
- if (frame_hdr->magic != 0xf1fa)
- {
- fprintf(stderr,"Frame_Header Error magic %lx not = 0xf1fa\n",frame_hdr->magic);
- TheEnd();
- }
- }
-
- void Read_Fli_File(fname)
- char *fname;
- {
- FILE *fin;
- int i,j,ret;
- ACTION *act;
-
-
- if ( (fin=fopen(fname,"r")) == 0)
- {
- fprintf(stderr,"can't open Fli File %s for reading\n",fname);
- TheEnd();
- }
-
- Read_Fli_Header(fin,&fli_hdr);
-
- fprintf(stderr," x=%ld y=%ld Frames = %ld\n",fli_hdr.width,
- fli_hdr.height,fli_hdr.frames);
-
- for(i=0;i<fli_hdr.frames;i++)
- {
- Read_Fli_Frame_Header(fin,&frame_hdr);
-
- if (frame_hdr.chunks==0) /* this frame is for timing purposes */
- {
- if (verbose) fprintf(stderr," ACT_DELAY Chunk\n");
- act = &action[action_cnt];
- action_cnt++;
- act->type = ACT_DELAY;
- if (jiffy_flag) act->time = jiffy_flag;
- else act->time = fli_hdr.speed * MS_PER_60HZ;
- act->data = 0;
- }
- else /* this frame has real data in it */
- {
- /* Loop through chunks in the frame
- */
- for(j=0;j<frame_hdr.chunks;j++)
- {
- ULONG chunk_size,chunk_type;
-
- act = &action[action_cnt];
- act->data = 0;
- action_cnt++;
-
- chunk_size = Fli_Get_Word(fin);
- chunk_type = Fli_Get_HalfWord(fin);
- switch(chunk_type)
- {
- case FLI_COLOR:
- if (verbose) fprintf(stderr," FLI_COLOR Chunk\n");
- Read_Fli_COLOR(fin,act);
- break;
-
- case FLI_LC:
- {
- ACT_FLI_LC_HDR *fli_lc_hdr;
-
- if (verbose) fprintf(stderr," FLI_LC\n");
- act->type = ACT_FLI_LC;
- if (jiffy_flag) act->time = jiffy_flag;
- else act->time = fli_hdr.speed * MS_PER_60HZ;
- fli_lc_hdr = (ACT_FLI_LC_HDR *)
- malloc( chunk_size-6 + sizeof(ACT_FLI_LC_HDR));
- if (fli_lc_hdr == 0) TheEnd1("Read_Fli_LC: malloc failed");
- act->data = (char *)(fli_lc_hdr);
- ret = fread( fli_lc_hdr->data, (chunk_size-6), 1, fin);
- if (ret != 1) TheEnd1("Read_Fli_LC: read failed");
- }
- break;
-
- case FLI_BLACK:
- if (verbose) fprintf(stderr," FLI_BLACK\n");
- if (chunk_size > 6)
- TheEnd1("Read_Fli_BLACK different than expected");
- act->type = ACT_FLI_BLACK;
- if (jiffy_flag) act->time = jiffy_flag;
- else act->time = fli_hdr.speed * MS_PER_60HZ;
- act->data = 0;
- break;
-
- case FLI_BRUN:
- if (verbose) fprintf(stderr," FLI_BRUN\n");
- act->type = ACT_FLI_BRUN;
- if (jiffy_flag) act->time = jiffy_flag;
- else act->time = fli_hdr.speed * MS_PER_60HZ;
- act->data = (char *) malloc( chunk_size-6 );
- if (act->data == 0) TheEnd1("Read_Fli_Brun: malloc failed");
- ret = fread( act->data, (chunk_size-6), 1, fin);
- if (ret != 1) TheEnd1("Read_Fli_Brun: read failed");
- break;
-
- case FLI_COPY:
- if (verbose) fprintf(stderr," FLI_COPY\n");
- act->type = ACT_FLI_COPY;
- if (jiffy_flag) act->time = jiffy_flag;
- else act->time = fli_hdr.speed * MS_PER_60HZ;
- act->data = (char *) malloc( chunk_size-4 );
- if (act->data == 0) TheEnd1("Read_Fli_COPY: malloc failed");
- ret = fread( act->data, (chunk_size-4), 1, fin);
- if (ret != 1) TheEnd1("Read_Fli_COPY: read failed");
- break;
- default:
- fprintf(stderr,"default size=%lx type=%lx\n",chunk_size,chunk_type);
- TheEnd();
- } /* end of switch */
- if (chunk_size & 0x01)
- {
- fprintf(stderr,"chunk_size=%lx ODD\n",chunk_size);
- }
- } /* end of chunks is frame */
- } /* end of not Timing Frame */
- } /* end of frames in file */
-
- fclose(fin);
- }
-
-
- /*
- * Routine to Decode a Fli BRUN chunk
- */
- void Decode_Fli_BRUN(data,image_out)
- unsigned char *data,*image_out;
- {
- ULONG i,j,k,packets,size,x,offset;
-
- for(i=0; i<imagey; i++)
- {
- offset = i * imagex;
- packets = *data++;
-
- x=0;
- for(j= 0; j < packets; j++)
- {
- size = *data++;
- if (size & 0x80) /* size < 0 so there is -size unique bytes */
- {
- size = 256-size;
- for(k= x; k < (x+size); k++) image_out[k+offset] = *data++;
- x += size;
- }
- else /* size is pos repeat next byte size times */
- {
- ULONG d;
- d = *data++;
- for(k= x; k < (x+size); k++) image_out[k+offset] = d;
- x+=size;
- }
- } /* end of packets per line */
- } /* end of line */
- }
-
- /*
- * Routine to Decode an Fli LC chunk
- */
- void Decode_Fli_LC(data,image_out,r_hdr)
- unsigned char *data,*image_out;
- REGION_HDR *r_hdr;
- {
- ULONG i,j,k,packets,size,x,offset;
- ULONG start,lines,skip,minx,maxx;
-
- start = *data++; start |= *data++ << 8; /* lines to skip */
- lines = *data++; lines |= *data++ << 8; /* number of lines */
-
- r_hdr->ypos = start;
- r_hdr->ysize = lines;
- minx = imagex;
- maxx = 0;
-
- for(i=start;i<(start+lines);i++)
- {
- offset = i * imagex;
- packets = *data++;
-
- x=0;
- for(j=0;j<packets;j++)
- {
- skip = *data++; /* this is the skip count */
- size = *data++;
-
- if (j==0) if (skip < minx) minx = skip;
- x+=skip;
- if (size==0)
- {
- size = *data++;
- fprintf(stderr,"size==0 what to we do? next is %ld\n",size);
- TheEnd();
- }
- if (size&0x80) /* next byte repeated -size times */
- {
- ULONG d;
- size = 256-size;
- d = *data++;
- for(k=x;k<(x+size);k++) image_out[k+offset] = d;
- x+=size;
- }
- else /* size is pos */
- {
- for(k=x;k<(x+size);k++) image_out[k+offset] = *data++;
- x+=size;
- }
- } /* end of packets per line */
- if (x > maxx) maxx = x;
- } /* end of line */
- r_hdr->xpos = minx;
-
- if (maxx > imagex) maxx=imagex;
- if (maxx > minx) r_hdr->xsize = maxx - minx;
- else r_hdr->xsize = imagex - minx;
-
- if (debug_flag) fprintf(stderr,"xypos=<%ld %ld> xysize=<%ld %ld>\n",
- r_hdr->xpos,r_hdr->ypos,r_hdr->xsize,r_hdr->ysize);
- }
-
- /*
- * Routine to read an Fli COLOR chunk
- */
- void Read_Fli_COLOR(fin,act)
- FILE *fin;
- ACTION *act;
- {
- ULONG i,k,l,packets,skip,colors,cnt;
- ColorReg *act_cmap;
- CMAP_HDR *cmap_hdr;
-
- act->type = ACT_CMAP;
- act->time = 0;
- cmap_hdr = (CMAP_HDR *)
- malloc( CMAP_SIZE * sizeof(ColorReg) + sizeof(CMAP_HDR));
- if (cmap_hdr == 0) TheEnd1("Fli_Read_COLOR: malloc failed\n");
- act->data = (char *)cmap_hdr;
- act_cmap = (ColorReg *)cmap_hdr->data;
- cmap_hdr->cmap_size = imagec;
-
- for(i=0;i<CMAP_SIZE;i++)
- {
- act_cmap[i].red = cmap[i].red;
- act_cmap[i].green = cmap[i].green;
- act_cmap[i].blue = cmap[i].blue;
- }
-
- packets = Fli_Get_HalfWord(fin);
- cnt=2;
- for(k=0;k<packets;k++)
- {
- skip = fgetc(fin);
- colors=fgetc(fin);
- cnt+=2;
- if (verbose) fprintf(stderr," skip=%ld colors=%ld\n",skip,colors);
- if (colors==0) colors=256;
- imagec=256;
- for(l=skip;l<(skip+colors);l++)
- {
- act_cmap[l].red = cmap[l].red = fgetc(fin)<<2;
- act_cmap[l].green = cmap[l].green = fgetc(fin)<<2;
- act_cmap[l].blue = cmap[l].blue = fgetc(fin)<<2;
- } /* end of colors */
- cnt+= 3 * colors;
- } /* end of packets */
- if (cnt&0x01) fgetc(fin); /* read pad byte if needed */
- }
-
-
- /*
- * Routine to read buffer Fli Actions from action_start up to
- * action_cnt.
- */
- void Fli_Buffer_Action(action_start)
- int action_start;
- {
- int i,pic_size;
- char *pic,*t_pic;
- ACTION *act;
-
- /* Allocate image buffer so deltas may be applied
- */
- pic_size = imagex * imagey;
- pic = (char *) malloc( pic_size );
- if (pic == 0) TheEnd1("BufferAction: malloc failed");
-
- for(i=action_start;i<action_cnt;i++)
- {
- act = &action[i];
- switch(act->type)
- {
- case ACT_DELAY:
- case ACT_CMAP:
- case ACT_IMAGE:
- case ACT_FLI_COLOR:
- case ACT_FLI_COPY:
- case ACT_FLI_BLACK:
- /* Clear to color 0
- */
- memset(pic,0x00,pic_size);
-
- t_pic = (char *) malloc( pic_size );
- if (t_pic == 0) TheEnd1("BufferAction: malloc failed");
- memset(t_pic,0x00,pic_size);
-
- act->type = ACT_IMAGE; /* change to image */
- free(act->data); /* free up encoded */
- act->data = t_pic; /* point to image */
- break;
- case ACT_FLI_BRUN:
-
- Decode_Fli_BRUN(act->data,pic);
-
- t_pic = (char *) malloc( pic_size );
- if (t_pic == 0) TheEnd1("BufferAction: malloc failed");
-
- memcpy(t_pic,pic,pic_size);
- act->type = ACT_IMAGE; /* change to image */
- free(act->data); /* free up encoded */
- act->data = t_pic; /* point to image */
-
- break;
- case ACT_FLI_LC:
- {
- ACT_FLI_LC_HDR *fli_lc_hdr;
- ACT_REGION_HDR *act_reg_hdr;
-
- fli_lc_hdr = (ACT_FLI_LC_HDR *)(act->data);
- Decode_Fli_LC(fli_lc_hdr->data, pic, fli_lc_hdr);
-
- /* Since an FLI LC chunk typically changes less
- * than the full image size, use a REGION to
- * store the changes.
- */
- act_reg_hdr = (ACT_REGION_HDR *)
- malloc(sizeof(ACT_REGION_HDR) + pic_size );
- if (act_reg_hdr == 0)
- TheEnd1("FLI BufferAction: malloc failed");
- memcpy((void *)act_reg_hdr->data,
- (void *)pic, pic_size);
- act->type = ACT_REGION; /* change to region */
- if (optimize_flag == TRUE)
- {
- act_reg_hdr->xpos = fli_lc_hdr->xpos;
- act_reg_hdr->ypos = fli_lc_hdr->ypos;
- act_reg_hdr->xsize = fli_lc_hdr->xsize;
- act_reg_hdr->ysize = fli_lc_hdr->ysize;
- }
- else
- {
- act_reg_hdr->xpos = 0;
- act_reg_hdr->ypos = 0;
- act_reg_hdr->xsize = imagex;
- act_reg_hdr->ysize = imagey;
- }
-
- free(act->data); /* free up encoded */
- act->data = (char *)act_reg_hdr; /* point to region */
- }
-
- break;
- default:
- fprintf(stderr,"Unknown not supported\n");
- }
- }
- free(pic);
- }
-
-
- /* Routine to read a little endian long word.
- * Note
- */
- ULONG Fli_Get_Word(fp)
- FILE *fp;
- {
- ULONG ret;
-
- ret = fgetc(fp);
- ret |= fgetc(fp) << 8;
- ret |= fgetc(fp) << 16;
- ret |= fgetc(fp) << 24;
- return ret;
- }
-
- /* Routine to read a little endian half word.
- */
- ULONG Fli_Get_HalfWord(fp)
- FILE *fp;
- {
- ULONG ret;
-
- ret = fgetc(fp);
- ret |= fgetc(fp) << 8;
- return ret;
- }
-
-